/*****************************************************************************
 * Copyright (C) 2019 Datastory Infomation Technology CO.LTD.
 * All Rights Reserved.
 * 本软件为数说故事信息技术有限公司开发研制。未经本公司正式书面同意，其他任何个人、团体不得使用、
 * 复制、修改或发布本软件.
 *****************************************************************************/

package com.craftplay.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 时间类型工具类（供所有项目共同使用）
 *
 * @author wangxiaokang
 * @since v1.0
 * 创建时间：2016年12月9日
 */
public final class DateUtils {

    //// 数据时间类型 1：24h 2: 今天 3：前1天 4：前7天 5：本周 6：前30天 7：本月
    public static final String LONG_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String LONG_DATE_FORMAT = "yyyy-MM-dd";
    public static final String SHORT_DATE_FORMAT = "yyyyMMdd";
    public static final String YEAR_MONTH_FORMAT = "yyyy-MM";
    public static final String YEAR_MONTH_SHORT_FORMAT = "yyyyMM";
    public static final String DAY_HOUR_FORMAT = "dd-HH时";
    public static final String YEAR_MONTH = "yyyy/MM";

    public static final String YEAR_FORMAT = "yyyy";
    public static final String MONTH_FORMAT = "MM";
    public static final String DATE_FORMAT = "dd";

    public static final String SPECAL_DATE_FORMAT = "yyyyMMddHHmmss";
    public static final String Day_MONTH_YEAR__FORMAT = "dd-MMM-yy";
    public static final String Day_MONTH_YEAR__FORMAT_LONG = "dd-MMM-yy hh24:mm";

    public static final String HOUR_MINS_FORMAT = "HH:mm";
    public static final String MONTH_DAY_FORMAT = "MM-dd";
    public static final String MONTH_DAY_HOUR_MIN_FORMAT = "MM-dd HH:mm";

    public static final String DB_TABLE_SUFFIX_DATE_FORMAT = "yyyyMMdd";

    /**
     * 获取指定日期往前推指定天的起始时刻
     *
     * @param date 之前日期
     * @param num  指定条数
     * @return 计算日期时间
     */
    public static Date getBeforeDayOfStartTime(Date date, int num) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.add(Calendar.DATE, -num);
        return calendar.getTime();
    }

    /**
     * 获取指定日期往前推指定天后的起始时刻
     *
     * @param date 之后日期
     * @param num  指定条数
     * @return 计算日期时间
     */
    public static Date getAfterDayOfStartTime(Date date, int num) {
        return getBeforeDayOfStartTime(date, -num);
    }


    /**
     * 将日期传换成时间戳
     *
     * @param date 指定时间
     * @return 长整形时间戳
     */
    public static long getTimestamp(Date date) {
        long l = 0l;
        try {
            Date start = new SimpleDateFormat(LONG_TIME_FORMAT).parse("1970-01-01 00:00:00");
            l = date.getTime() - start.getTime() > 0 ? date.getTime() : start.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return l / 1000;
    }

    /**
     * 格式化时间类型（格式为yyyy-MM-dd HH:mm:ss）
     *
     * @param date 待格式化时间
     * @return 格式化后的时间字符串
     */
    public static String dateToLongString(Date date) {
        DateFormat formatter = new SimpleDateFormat(LONG_TIME_FORMAT);
        String strDate = formatter.format(date);
        return strDate;
    }

    /**
     * 格式化时间类型（格式为yyyyMMddHHmmss）
     *
     * @param date 待格式化时间
     * @return 格式化后的时间字符串
     */
    public static String dateToSpecalString(Date date) {
        DateFormat formatter = new SimpleDateFormat(SPECAL_DATE_FORMAT);
        String strDate = formatter.format(date);
        return strDate;
    }




    /**
     * 将长整形时间戳传换成日期
     *
     * @param longDate 长整形时间(单位为秒)
     * @return 时间
     */
    public static Date timestampToDate(long longDate) {
        Date date = new Date(longDate * 1000);
        return date;
    }

    /**
     * 将长整形时间戳传换成时间字符串
     *
     * @param longDate 长整形时间
     * @return 时间(格式为 " yyyy - MM - dd HH : mm : ss ")
     */
    public static String timestampToString(long longDate) {
        DateFormat formatter = new SimpleDateFormat(LONG_TIME_FORMAT);
        return formatter.format(timestampToDate(longDate));
    }

    /**
     * 字符串时间转Date
     *
     * @param value 时间字符串
     * @return 时间
     */
    public static Date stringToDate(String value) {
        DateFormat formatter = new SimpleDateFormat(LONG_TIME_FORMAT);
        Date date = null;
        try {
            date = formatter.parse(value);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 格式化时间的简短型年月(格式为yyyyMM, 如201610表示2016年10月)
     *
     * @param value 待格式化时间
     * @return 格式化后的年月字符串
     */
    public static String formatToShortYearAndMonth(Date value) {
        DateFormat formatter = new SimpleDateFormat(YEAR_MONTH_SHORT_FORMAT);
        String date = formatter.format(value);
        return date;
    }

    /**
     * 格式化时间的简短型年月(格式为yyyyMMdd, 如20161030表示2016年10月31日)
     *
     * @param value 待格式化时间
     * @return 格式化后的年月字符串
     */
    public static String formatToShortDay(Date day) {
        DateFormat formatter = new SimpleDateFormat(SHORT_DATE_FORMAT);
        String date = formatter.format(day);
        return date;
    }

    /**
     * 格式化时间的简短型年月(格式为yyyyMMdd, 如20161030表示2016年10月31日)
     *
     * @param value 待格式化时间
     * @return 格式化后的年月字符串
     */
    public static String formatToLongDay(Date day) {
        DateFormat formatter = new SimpleDateFormat(LONG_DATE_FORMAT);
        String date = formatter.format(day);
        return date;
    }

    /**
     * 格式化长日期型字符串为指定天数的开始时间
     *
     * @param value 长日期型字符串
     * @return 日期开始时间
     */
    public static Date getStartTimeOfDayByStr(String value) {
        Calendar calendar = Calendar.getInstance();
        DateFormat formatter = new SimpleDateFormat(LONG_DATE_FORMAT);
        Date date = null;
        try {
            date = formatter.parse(value);
            calendar.setTime(date);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return calendar.getTime();
    }

    /**
     * 格式化长日期型字符串为指定天数的结束时间
     *
     * @param value 长日期型字符串
     * @return 日期开始时间
     */
    public static Date getEndTimeOfDayByStr(String value) {
        Calendar calendar = Calendar.getInstance();
        DateFormat formatter = new SimpleDateFormat(LONG_DATE_FORMAT);
        Date date = null;
        try {
            date = formatter.parse(value);
            calendar.setTime(date);
            calendar.set(Calendar.HOUR_OF_DAY, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return calendar.getTime();
    }

    public static List<String> getListDaysBefore(Date date, int number) {
        List<String> lstDate = new ArrayList<String>();
        for (int i = 0; i < number; i++) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.add(Calendar.DATE, -i);
            lstDate.add(formatToLongDay(calendar.getTime()));
        }
        return lstDate;
    }

    public static List<String> getListHoursBeforeOfOneDay(Date date, int number) {
        List<String> lstHour = new ArrayList<String>();
        for (int i = 0; i < number; i++) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.HOUR_OF_DAY, -i);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.DATE, 0);
            lstHour.add(dateToLongString(calendar.getTime()));
        }
        return lstHour;
    }

    public static String getCurrentDateBySetHour(int hour) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return dateToLongString(calendar.getTime());
    }

    public static List<String> get5MinutesInCurrentOneHuour(Date date) {
		/*SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH");
		date = stringToDate(sdf.format(date)+":00:00");*/
        List<String> result = new ArrayList<String>();
        for (int i = 0; i < 13; i++) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.MINUTE, -i * 5);
            calendar.set(Calendar.SECOND, 0);
            result.add(dateToLongString(calendar.getTime()));
        }
        return result;
    }


    /**
     * 时间格式第一种 yyyy-MM-dd
     */
    public static final String FORMAT_ONE = "yyyy-MM-dd";
    /**
     * 时间格式第二种 yyyy-MM-dd HH:mm:ss
     */
    public static final String FORMAT_TWO = "yyyy-MM-dd HH:mm:ss";
    /**
     * 时间格式第一种 yyyy-MM
     */
    public static final String FORMAT_THREE = "yyyy-MM";
    /**
     * 时间格式第二种 yyyyMMddHHmmss
     */
    public static final String FORMAT_FOUR = "yyyyMMddHHmmss";

    public static final String FORMAT_MDHMS = "MMddHHmmss";
    public static final String FORMAT_DHI = "ddHHmm";
    public static final String FORMAT_MDHM = "MMddHHmm";

    public static final String FORMAT_MDHM000000 = "yyyy-MM-dd 00:00:00";

    public static final String FORMAT_MDHM235959 = "yyyy-MM-dd 23:59:59";


    public static final long DAY = 24 * 60 * 60 * 1000;
    public static final long HOUR = 60 * 60 * 1000;
    public static final long MINUTE = 60 * 1000;


    public static String LOG_SUFFIX = null;

    /**
     * 获取日志的前后缀
     *
     * @return
     */
    public static String getSuffix() {
        if (LOG_SUFFIX == null) {
            LOG_SUFFIX = DateUtils.getYearAndNowMonth();
        }
        return LOG_SUFFIX;
    }

    /**
     * 将String类型的时间转化成Date类型的时间
     *
     * @param time   时间
     * @param format 格式
     * @return
     */
    public static Date stringToDate(String time, String format) {
        if (time == null || "".equals(time))
            return new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        try {
            Date date = dateFormat.parse(time);
            return date;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将Date类型的时间转化成String类型的时间
     *
     * @param time   时间
     * @param format 格式
     * @return
     */
    public static String dateToString(Date time, String format) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        String date = dateFormat.format(time);
        return date;
    }

    /**
     * 获取当前时间 格式 yyyy-MM-dd HH:mm:ss
     *
     * @return
     */
    public static String getNOW() {
        return DateUtils.dateToString(new Date(), FORMAT_TWO);
    }

    /**
     * 自定义获取当前时间
     *
     * @param format
     * @return
     */
    public static String getNOW(String format) {
        return DateUtils.dateToString(new Date(), format);
    }

    /**
     * 将时间戳转化成String类型的时间
     *
     * @param time   时间戳
     * @param format 格式
     * @return
     */
    public static String dateToString(long time, String format) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        String date = dateFormat.format(time);
        return date;
    }

    /**
     * 验证指定时间是否是当天
     *
     * @param time
     * @return true: 是同一天
     */
    public static boolean compareData(long time) {
        return compareData(dateToString(time, FORMAT_ONE));
    }

    /**
     * 验证当前时间的day是否与当前时间day相等
     *
     * @return 同一天/true
     */
    public static boolean compareData(Date time) {
        if (time == null) return false;
        return dateToString(time, FORMAT_ONE).equals(dateToString(new Date(), FORMAT_ONE));
    }

    /**
     * 验证当day是否相等
     *
     * @param time1
     * @param time2
     * @return 同一天/true
     */
    public static boolean compareData(Date time1, Date time2) {
        if (time1 == null || time2 == null) return time1 == time2;
        return dateToString(time1, FORMAT_ONE).equals(dateToString(time2, FORMAT_ONE));
    }

    /**
     * 验证当前时间的day是否与当前时间day相等
     *
     * @return 同一天/true
     */
    public static boolean compareData(String time) {
        return time.equals(dateToString(new Date(), FORMAT_ONE));
    }


    public static boolean canInitLogTable() {
        Calendar calendar = Calendar.getInstance();
        int maxDay = calendar.getActualMaximum(Calendar.DATE);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        return maxDay == day;
    }

    public static String getYearAndNowMonth() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.YEAR) + "" + (calendar.get(Calendar.MONTH) + 1);
    }

    public static String getLogTalbeSuffix() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.YEAR) + "" + (calendar.get(Calendar.MONTH) + 2);
    }

    /**
     * 获取一天的起始时间
     *
     * @param date
     * @return
     */
    public static Date getStartOfDate(Date date) {
        String nowTime = DateUtils.dateToString(date, FORMAT_ONE);
        return DateUtils.stringToDate(nowTime, FORMAT_ONE);
    }

    /**
     * 获取一天已过时间
     */
    public static long getPassTime() {
        Date d = DateUtils.getStartOfDate(new Date());
        return System.currentTimeMillis() - d.getTime();
    }

    /**
     * 获取一天剩余时间
     */
    public static long getlessTime() {
        return (DAY - getPassTime()) / 1000;
    }

    /**
     * 用于固定时间刷新
     * 判断今天是否到了某个时间点
     */
    public static boolean compareNowHour(int hour) {
        long time = hour * DateUtils.HOUR;

        return DateUtils.getPassTime() >= time;
    }

    /**
     * 用于固定时间刷新
     * 判断记录的时间是否在固定时间之前
     * 若是可执行刷新操作
     */
    public static boolean compareFixHour(int hour, Date d) {
        long recordTime = d.getTime();
        long fixedTime = hour * DateUtils.HOUR + DateUtils.getStartOfDate(new Date()).getTime();
        return recordTime < fixedTime;
    }

    /**
     * 用于固定时间刷新
     * 判断记录的时间是否在固定时间之前
     * 并且是否到了某个时间点
     * 若是可执行刷新操作
     */
    public static boolean canRefresh(int hour, Date d) {
        return compareFixHour(hour, d) && compareNowHour(hour);
    }

    public static boolean isUseDb() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.HOUR_OF_DAY) == 0 && calendar.get(Calendar.MINUTE) == 1;
    }

    /**
     * 获取剩余时间
     *
     * @param startTime 开始时间
     * @param duration  持续时间
     * @return 剩余时间(毫秒)
     */
    public static long getLeftTime(long startTime, long duration) {
        return Math.max(0, (startTime + duration) - System.currentTimeMillis());
    }

    /**
     * 获取start + day的时间
     *
     * @param start
     * @param day
     * @return
     */
    public static Date addTime(Date start, long dayTimes) {
        long max = dayTimes + start.getTime();
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(max);
        return cal.getTime();
    }

    /**
     * 对比两个时间相差天数
     *
     * @param start 时间1
     * @param end   时间2
     * @return
     */
    public static int daysOfTwo(long start, long end) {
        Calendar aCalendar = Calendar.getInstance();
        aCalendar.setTimeInMillis(start);
        int day1 = aCalendar.get(Calendar.DAY_OF_YEAR);
        aCalendar.setTimeInMillis(end);
        int day2 = aCalendar.get(Calendar.DAY_OF_YEAR);
        return day2 - day1;
    }


    public static void main(String[] args) {
        System.out.println(getLogTalbeSuffix());
        System.out.println(canInitLogTable());
    }

    public static int time() {
        return (int) (System.currentTimeMillis() / 1000);
    }


    /**
     * 当前凌晨剩余秒
     *
     * @return
     */
    public static int getSurplusTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        int less = (int) (calendar.getTimeInMillis() - System.currentTimeMillis()) / 1000;
        return less;
    }

    /**
     * 时间戳
     *
     * @return
     */
    public static String getTimeStamp() {
        return String.valueOf(System.currentTimeMillis() / 1000);
    }


    /**
     * 获得一天的零点时间
     * yyyy-MM-dd 00:00:00
     */
    public static String formatToBeginDay(Date day) {
        DateFormat formatter = new SimpleDateFormat(FORMAT_MDHM000000);
        String date = formatter.format(day);
        return date;
    }

    /**
     * 获得一天的结束时间
     * yyyy-MM-dd 23:59:59
     */
    public static String formatToEndDay(Date day) {
        DateFormat formatter = new SimpleDateFormat(FORMAT_MDHM235959);
        String date = formatter.format(day);
        return date;
    }


    public static Date addSubDay(Date date,int i) {
        Calendar   calendar   =   new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(calendar.DATE,i);//把日期往后增加一天.整数往后推,负数往前移动
        date=calendar.getTime();
        return date;
    }


}
